package domain.command;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import org.dsrg.soenea.domain.MapperException;
import org.dsrg.soenea.domain.command.CommandError;
import org.dsrg.soenea.domain.command.CommandException;
import org.dsrg.soenea.domain.command.impl.Command;
import org.dsrg.soenea.domain.helper.Helper;
import org.dsrg.soenea.domain.mapper.DomainObjectNotFoundException;
import org.dsrg.soenea.domain.role.IRole;
import org.dsrg.soenea.uow.UoW;

import domain.JavaMD5Hashing;
import domain.model.group.Group;
import domain.model.group.GroupProxy;
import domain.model.group.IGroup;
import domain.model.group.mapper.GroupInputMapper;
import domain.model.invite.IInvite;
import domain.model.person.IPerson;
import domain.model.person.Person;
import domain.model.person.PersonFactory;
import domain.model.person.PersonProxy;
import domain.model.person.data.PersonTDG;
import domain.model.person.mapper.PersonInputMapper;
import domain.model.role.StudentRole;
import domain.model.role.AdminRole;
import domain.model.user.User;
import domain.model.user.UserFactory;
import domain.model.user.data.UserTDG;
import domain.model.user.mapper.UserInputMapper;
import domain.model.user.mapper.UserOutputMapper;

public class AddSingleUserCommand extends Command{

	
	public AddSingleUserCommand(Helper helper) 
	{
		super(helper);
		// TODO Auto-generated constructor stub

	}

	@Override
	public void setUp() throws CommandException 
	{
		// TODO Auto-generated method stub
	}


	@Override
	public void process() throws CommandException 
	{
		try
		{
			
			String un, pw, fn, ln;
			long ut;
			
			ut = helper.getLong("userType");
			un = helper.getString("userName");
				
			//convert user written password into a standardized hash md5, which is how we store it in the DB
			pw = JavaMD5Hashing.produceMD5Hash(helper.getString("password")); 
				
			fn = helper.getString("firstName");
			ln = helper.getString("lastName");
			
				
			if(ut == 0 || un == "" || un == null || pw == "" || pw == null || fn == "" || fn == null || ln == "" || ln == null)
				{
					throw new CommandException();
				}
				
			//debug
			//System.out.println("usertype: " + ut + " user: " + un + " pw: " + pw + " fn: " + fn + " ln:" + ln);
			//System.out.println("largest user id: " + PersonTDG.getMaxID());
			
			List<IRole> roles = new ArrayList<IRole>();
			long mID = PersonTDG.getMaxID() + 1;
			
			//Giving proper access, then creating the user
			if (ut == 2) //Student
			{
				StudentRole sr = new StudentRole();
				roles.add(sr);
			}
			else if (ut == 3) //Admin
			{
				AdminRole ar = new AdminRole();
				roles.add(ar);
			}
			else
			{
				throw new CommandException();
			}
			
			
			 //Person createNew(long id, String username, String password, List<IRole> roles, IUser user)
			Person p = PersonFactory.createNew(mID, un, pw, roles, null);
			
			//User createNew(long id, IGroup group, String firstname, String lastname, IPerson person)
			IGroup group = new GroupProxy((long) 0);
			User u = UserFactory.createNew(mID, group, fn, ln, p);
			p.setUser(u);
			
			/*
    		PersonOutputMapper pom = new PersonOutputMapper();
    		UserOutputMapper uom = new UserOutputMapper();
    		
    		pom.insert(p);
    		uom.insert(u);
    		*/
    		UoW.getCurrent().registerNew(p);
    		UoW.getCurrent().registerNew(u);
			
			UoW.getCurrent().commit();
			
			
			//To fix the bug with linking the person.ID to users.person we need to find the person.ID and do an update on the user table
			
			//first find the ID for the person with username = un
			List<Person> personlist = new ArrayList<Person>();

			try 
			{
				personlist = PersonInputMapper.findAll();
			} 
			catch (SQLException e) 
			{
				throw new CommandException("DB error: " + e.getMessage());
			} catch (DomainObjectNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			//long newID = 0;
			Person newPerson = null;
			
			for(Person per: personlist)
			{
				if(un.equals(per.getUsername()))
				{
					//newID = per.getId();
					newPerson = per;
					//System.out.println("person table ID:" +newID);
					break;
				}
			}
			
			long newID2 = 0;
			newID2 = UserTDG.getMaxID();
			//System.out.println("MAXuser table ID:" +newID2);
			
			//Now find the same person in the users table
			/*
			List<User> userlist = new ArrayList<User>();
			
			try
			{
				userlist = UserInputMapper.findAll();  //CODE IS FAILING HERE BECAUSE ITS NOT GETTING ALL USERS DUE to the identity map already loaded...
			}
			catch (SQLException e) 
			{
				throw new CommandException("DB error: " + e.getMessage());
			} 
			
			long newID2 = 0;
			
			for(User usercheck: userlist)  //getting the ID of the user
			{
				if(fn.equalsIgnoreCase(usercheck.getFirstName()))
				{
					if(ln.equalsIgnoreCase(usercheck.getLastName()))
					{
						newID2 = usercheck.getId();
						System.out.println("users table ID:" +newID2);
						break;
					}
				}
			}
			
			*/
			
			//This is really bad.. shouldnt go directly to the TDG...
			//update(long userid, long version, long groupid, String firstname, String lastname, long person)
			//UserTDG.update(newID2, 2, 0, fn, ln, newID);
			
			User newU = UserInputMapper.find(newID2);
			//PersonProxy pNew = new PersonProxy(newID);
			newU.setPerson(newPerson);
			
			UserOutputMapper uom = new UserOutputMapper();
			uom.update(newU);
			
			String title = "Create New Users";
			String success = "Successfully Added New User!";
			helper.setRequestAttribute("title", title);
			helper.setRequestAttribute("added", success);
			
			
		}
		
		catch (SQLException e) 
		{
			throw new CommandException(e);
			//e.printStackTrace();
		} 
		catch (DomainObjectNotFoundException e) 
		{
			// TODO Auto-generated catch block
			throw new CommandException(e);
		}
		catch (MapperException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		catch (InstantiationException e1) 
		{
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} 
		catch (IllegalAccessException e1) 
		{
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	@Override
	public void tearDown() throws CommandError 
	{
		// TODO Auto-generated method stub
		
	}	
	
}
